﻿Imports System.IO, EnvDTE

Public Module Extensions


    ''' <summary>
    ''' COMMENT THIS ASAP
    ''' </summary>
    ''' <typeparam name="T"></typeparam>
    ''' <param name="rootElement"></param>
    ''' <param name="alreadyFoundElements"></param>
    ''' <param name="findSubElementsFunction"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    ''' <stepthrough></stepthrough>
    <System.Runtime.CompilerServices.Extension()>
    Public Function GetRecursive(Of T)(ByVal rootElement As T, ByVal alreadyFoundElements As IList(Of T), ByVal findSubElementsFunction As Func(Of T, IList(Of T), IEnumerable(Of T))) As IEnumerable(Of T)
        Dim subElements = findSubElementsFunction(rootElement, alreadyFoundElements).ToList()
        If subElements.Count = 0 OrElse subElements Is Nothing Then
            Return New T() {}
        End If
        alreadyFoundElements = alreadyFoundElements.Union(subElements).ToList()
        For Each subE As T In subElements
            alreadyFoundElements = alreadyFoundElements.Union(subE.GetRecursive(alreadyFoundElements, findSubElementsFunction)).ToList()
        Next
        Return alreadyFoundElements
    End Function


    ''' <summary>
    ''' Returns A New ReferenceResolver so you can Grab all the needed References (Improve Wording)
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    ''' <stepthrough></stepthrough>
    Public Function GetResolver() As ReferenceResolver '(ByVal debugger As Debugger)
        '<System.Runtime.CompilerServices.Extension()>
        Dim Debugger = Mod_Utilities.DTE.Debugger       'Use This...This Should be Much Faster
        Dim assemblyLocation As String = String.Empty   'Get all referenced assemblies


        'Why are we looping Through this O.o?
        'The Same Exact thing is Happening 9 times from what I see
        For i As Integer = 0 To 9
            Try
                If Mod_Utilities.Versioning.Language = Mod_Utilities.Versioning.Languages.CSharp Then
                    assemblyLocation = Debugger.GetExpression("System.Reflection.Assembly.GetExecutingAssembly().Location;", False, 5000).Value
                Else
                    assemblyLocation = Debugger.GetExpression("System.Reflection.Assembly.GetExecutingAssembly().Location", False, 5000).Value
                End If

                assemblyLocation = assemblyLocation.Replace("\\", "\").Replace("""", "")
                'Date: 10/23/2011   Aaron: Commented out the 3 Lines Below; The Seem to do nothing at all
                'If File.Exists(assemblyLocation) Then
                '    Exit Try
                '    'es kann auch eine Message wie "Function evaluation timed out" zurückkommen
                'End If
            Catch
                System.Threading.Thread.Sleep(50)
            End Try
        Next
        If Not File.Exists(assemblyLocation) OrElse String.IsNullOrEmpty(assemblyLocation) Then Return Nothing
        Return New ReferenceResolver(assemblyLocation)
    End Function

    '<System.Runtime.CompilerServices.Extension()>
    ''' <summary>
    ''' 
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    ''' <stepthrough></stepthrough>
    Public Function GetCurrentType() As Type
        Dim Debugger = Mod_Utilities.DTE.Debugger, currentClassType As Type = Nothing
        Dim Filler = If(Mod_Utilities.Versioning.Language = Mod_Utilities.Versioning.Languages.VB, "Me", "this")


        Dim typeFullnameExpr As Expression = Debugger.GetExpression(Filler & ".GetType().FullName", False, 2000)
        Dim className As String = typeFullnameExpr.Value.Replace("""", "")
        If className.Contains("'" & Filler & "'") Then
            className = Debugger.CurrentStackFrame.FunctionName
            If className.Contains(".") Then
                className = className.Substring(0, className.LastIndexOf("."))
            End If
        End If

        currentClassType = (From t In GetResolver.RootAssembly.GetTypes()
                            Where LocalMember.RepairTypeName(t.FullName, t) = className
                            Select t).FirstOrDefault()

        Return currentClassType
    End Function

End Module
